package com.ruoyi.system.service.impl;

import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.Encryption;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.domain.vo.PlatMenuVO;
import com.ruoyi.system.domain.vo.PlatMenusVO;
import com.ruoyi.system.domain.vo.PlatTecturer;
import com.ruoyi.system.mapper.*;
import com.ruoyi.system.service.IPlatLessonService;
import com.ruoyi.system.service.IPlatTokenService;
import com.ruoyi.system.service.IPlatUserService;
import jxl.Cell;
import jxl.Workbook;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.*;


@Service
public class PlatUserServiceImpl extends PlatCommonServiceImpl implements IPlatUserService {

    @Autowired
    private PlatUserMapper platUserMapper;
    @Autowired
    private IPlatTokenService platTokenService;
    @Autowired
    private PlatMenuMapper platMenuMapper;
    @Autowired
    private PlatClassMapper platClassMapper;
    @Autowired
    private PlatCollegeMapper platCollegeMapper;
    @Autowired
    private PlatMajorMapper platMajorMapper;
    @Autowired
    private PlatLessonMapper platLessonMapper;
    @Autowired
    private IPlatLessonService platLessonService;
    @Autowired
    private PlatLessonStudentMapper platLessonStudentMapper;

    /**
     * 登录验证
     *
     * @param username 用户名
     * @param password 密码
     * @return 结果
     */
    public String login(String username, String password) {
        if (StringUtils.isEmpty(username)) {
            throw new BusinessException("账号不能为空");
        }

        if (StringUtils.isEmpty(password)) {
            throw new BusinessException("密码不能为空");
        }

        PlatUser platUser = platUserMapper.selectByNumber(username);
        if (platUser == null) {
            throw new BusinessException("用户名不存在");
        }

        if (!password.equals(platUser.getPassword())) {
            throw new BusinessException("密码错误");
        }

        if (platUser.getStatus() == null || platUser.getStatus() != 1) {
            throw new BusinessException("该账号已停用");
        }

        //记录登录时间
        platUser.setLoginDate(DateUtils.getNowDate());
        platUserMapper.updateByPrimaryKey(platUser);

        // 生成token
        return platTokenService.createToken(platUser);
    }

    @Override
    public List<PlatMenuVO> getMenu(PlatUser loginUser) {
        List<PlatMenuVO> result = new ArrayList<>();

        List<PlatMenu> list = platMenuMapper.selectMenu(null, IDENTIFICATION + loginUser.getRole() + IDENTIFICATION);
        for (PlatMenu platMenu : list) {
            PlatMenuVO platMenuVO = new PlatMenuVO();
            platMenuVO.setName(platMenu.getComponent());
            platMenuVO.setTitle(platMenu.getMenuName());
            platMenuVO.setIcon(platMenu.getIcon());
            List<PlatMenusVO> platMenusVOList = new ArrayList<>();

            List<PlatMenu> lists = platMenuMapper.selectMenu(platMenu.getMenuId(), IDENTIFICATION + loginUser.getRole() + IDENTIFICATION);
            for (PlatMenu platMenus : lists) {
                PlatMenusVO platMenusVO = new PlatMenusVO();
                platMenusVO.setName(platMenus.getComponent());
                platMenusVO.setTitle(platMenus.getMenuName());
                platMenusVOList.add(platMenusVO);
            }
            platMenuVO.setList(platMenusVOList);
            result.add(platMenuVO);
        }
        return result;
    }

    @Override
    public void updateUserInfo(HttpServletRequest request, PlatUser platUser) {
        PlatUser platUserPO = platUserMapper.selectByNumber(platUser.getUserName());
        if (platUserPO == null) {
            throw new BusinessException("用户不存在");
        }
        platUser.setUpdateBy(getTokenUser());
        platUser.setUpdateTime(new Date());
        platUser.setId(platUserPO.getId());
        platUserMapper.updateByPrimaryKeySelective(platUser);
    }

    @Override
    public PlatUser getLoginUser(HttpServletRequest request) {
        PlatUser loginUser = platTokenService.getLoginUser(request);
        return platUserMapper.selectByNumber(loginUser.getUserName());
    }

    @Override
    public void updatePassword(HttpServletRequest request, PlatUser platUser) {
        PlatUser platUserPO = platUserMapper.selectByNumber(getLoginUser(request).getUserName());
        if (platUserPO == null) {
            throw new BusinessException("用户不存在");
        }
        if (StringUtils.isEmpty(platUser.getOldPassword())) {
            throw new BusinessException("旧密码不能为空");
        }
        if (StringUtils.isEmpty(platUser.getPassword())) {
            throw new BusinessException("新密码不能为空");
        }

        if (!platUser.getOldPassword().equals(platUserPO.getPassword())) {
            throw new BusinessException("旧密码错误");
        }
        //修改密码
        platUserPO.setPassword(platUser.getPassword());
        platUserMapper.updateByPrimaryKey(platUserPO);
    }

    @Override
    public List<PlatUser> studentList(HttpServletRequest request, PlatUser platUser) {
        Integer[] roles = {ROLE_STUDENT};
        List<PlatUser> list = getMyTeacherList(platUser, roles);
        return getInitUserList(list);
    }

    @Override
    public void delUser(Long id) {
        PlatUser platUserPO = platUserMapper.selectByPrimaryKey(id);
        if (platUserPO != null && ROLE_SUPER_ADMIN == platUserPO.getRole()) {
            throw new BusinessException(roleMap.get(ROLE_SUPER_ADMIN) + "不能删除！");
        }
        platUserMapper.deleteByPrimaryKey(id);
    }


    @Override
    public String uploadFileStudent(Workbook workbook, Cell cell, HttpServletRequest request) {
        //返回信息
        StringBuffer resultErrorBuffer = new StringBuffer();

        //得到列数
        int allColsNum = workbook.getSheet(0).getColumns();

        //所属区域
        List<String> userNameList = getExcelList(cell, workbook.getSheet(0), "用户账号(必填)", allColsNum);
        List<String> nickNameList = getExcelList(cell, workbook.getSheet(0), "用户名称(必填)", allColsNum);
        List<String> classList = getExcelList(cell, workbook.getSheet(0), "所属班级(必填)", allColsNum);
        List<String> emailList = getExcelList(cell, workbook.getSheet(0), "邮箱(非必填)", allColsNum);
        List<String> mobileList = getExcelList(cell, workbook.getSheet(0), "联系电话(非必填)", allColsNum);

        //记录次数
        int successNum = 0;

        for (int i = 0; i < userNameList.size(); i++) {
            if (nickNameList.size() > i && classList.size() > i && emailList.size() > i && mobileList.size() > i &&
                    !StringUtils.isEmpty(userNameList.get(i)) && !StringUtils.isEmpty(nickNameList.get(i)) && !StringUtils.isEmpty(classList.get(i))) {
                PlatUser platUser = new PlatUser();

                String className = classList.get(i).replace(" ", "");
                PlatClassExample platClassExample = new PlatClassExample();
                PlatClassExample.Criteria criteria = platClassExample.createCriteria();
                criteria.andNameEqualTo(className);
                List<PlatClass> platClassList = platClassMapper.selectByExample(platClassExample);
                Boolean classFlag = false;
                if (platClassList.size() == 1) {
                    platUser.setClassId(platClassList.get(0).getId());
                    classFlag = true;
                }

                platUser.setUserName(userNameList.get(i));
                platUser.setNickName(nickNameList.get(i));
                platUser.setEmail(emailList.get(i));
                platUser.setMobile(mobileList.get(i));
                platUser.setRole(ROLE_STUDENT);
                platUser.setPassword(DEFAULT_PASSWORD);
                platUser.setStatus(1);

                if(classFlag){
                    try {
                        //修改
                        PlatUser platUserPO = platUserMapper.selectByNumber(platUser.getUserName());
                        if (platUserPO != null) {
                            platUser.setId(platUserPO.getId());
                        }
                        //添加
                        addTeacher(request, platUser);
                        successNum++;
                    } catch (BusinessException e) {
                        if (resultErrorBuffer.length() != 0) {
                            resultErrorBuffer.append("，");
                        }
                        resultErrorBuffer.append(platUser.getUserName() + ":" + e.getMsg());
                    } catch (Exception e) {
                        error("操作失败", e);
                        if (resultErrorBuffer.length() != 0) {
                            resultErrorBuffer.append("，");
                        }
                        resultErrorBuffer.append(platUser.getUserName() + ":导入失败");
                    }
                }else{
                    if (resultErrorBuffer.length() != 0) {
                        resultErrorBuffer.append("，");
                    }
                    resultErrorBuffer.append(platUser.getUserName() + ":" + "班级无效");
                }
            }
        }
        String msg = "总数：" + userNameList.size() + "，成功数：" + successNum;
        if (resultErrorBuffer.length() != 0) {
            msg += "，失败信息学号:" + resultErrorBuffer.toString();
        }
        return msg;
    }

    @Override
    public List<PlatUser> teacherList(HttpServletRequest request, PlatUser platUser) {
        Integer[] roles = {ROLE_ADMIN, ROLE_TEACHER};
        List<PlatUser> list = getMyTeacherList(platUser, roles);
        return getInitUserList(list);
    }

    private List<PlatUser> getInitUserList(List<PlatUser> list) {
        for (PlatUser platUserPO : list) {
            if (platUserPO.getCollegeId() != null) {
                PlatCollege platCollege = platCollegeMapper.selectByPrimaryKey(platUserPO.getCollegeId());
                if (platCollege != null) {
                    platUserPO.setCollegeName(platCollege.getName());
                }
            }
            if (platUserPO.getMajorId() != null) {
                PlatMajor platMajor = platMajorMapper.selectByPrimaryKey(platUserPO.getMajorId());
                if (platMajor != null) {
                    platUserPO.setMajorName(platMajor.getName());
                }
            }
            if (platUserPO.getClassId() != null) {
                PlatClass platClass = platClassMapper.selectByPrimaryKey(platUserPO.getClassId());
                if (platClass != null) {
                    platUserPO.setClassName(platClass.getName());
                }
            }
        }
        return list;
    }

    @Override
    public List<PlatTecturer> lecturerList(Long classId) {
        //返回集合
        List<PlatTecturer> resultList = new ArrayList<>();

        PlatClass platClass = platClassMapper.selectByPrimaryKey(classId);
        Integer[] roles = {ROLE_TEACHER};
        List<PlatUser> platUserList = getMyTeacherList(null, roles);
        for (PlatUser platUser : platUserList) {
            PlatTecturer platTecturer = new PlatTecturer();
            platTecturer.setName(platUser.getNickName());
            platTecturer.setValue(platUser.getId());
            platTecturer.setSelected(false);
            if (platClass != null && platClass.getTeacher() != null && platClass.getTeacher().contains(IDENTIFICATION + platUser.getId() + IDENTIFICATION)) {
                platTecturer.setSelected(true);
            }
            resultList.add(platTecturer);
        }
        return resultList;
    }

    @Override
    public List<PlatTecturer> lecturerLessonList(Long classId) {
        //返回集合
        List<PlatTecturer> resultList = new ArrayList<>();

        PlatLesson platLesson = platLessonMapper.selectByPrimaryKey(classId);
        Integer[] roles = {ROLE_TEACHER};
        List<PlatUser> platUserList = getMyTeacherList(null, roles);
        for (PlatUser platUser : platUserList) {
            PlatTecturer platTecturer = new PlatTecturer();
            platTecturer.setName(platUser.getNickName());
            platTecturer.setValue(platUser.getId());
            platTecturer.setSelected(false);
            if (platLesson != null && platLesson.getTeachers() != null && platLesson.getTeachers().contains(IDENTIFICATION + platUser.getId() + IDENTIFICATION)) {
                platTecturer.setSelected(true);
            }
            resultList.add(platTecturer);
        }
        return resultList;
    }

    @Override
    public void addTeacher(HttpServletRequest request, PlatUser platUser) {
        //登录者
        PlatUser loginUser = getLoginUser(request);

        if("".equals(platUser.getPassword())){
            platUser.setPassword(null);
        }

        //密码
        if (!StringUtils.isEmpty(platUser.getPassword())) {
            platUser.setPassword(Encryption.md5s(platUser.getPassword()));
        }


        //角色名称
        platUser.setRoleName(roleMap.get(platUser.getRole()));

        String resource = "教师工号";
        if (platUser.getClassId() != null) {//添加学生，否则是添加教师
            resource = "学生学号";
            PlatClass platClass = platClassMapper.selectByPrimaryKey(platUser.getClassId());
            if (platClass != null) {
                platUser.setCollegeId(platClass.getCollegeId());
                platUser.setMajorId(platClass.getMajorId());
            }
        }

        if (platUser.getId() != null) {
            PlatUser platUserPO = platUserMapper.selectByNumber(platUser.getUserName());
            if (platUserPO != null && !String.valueOf(platUserPO.getId()).equals(String.valueOf(platUser.getId()))) {
                throw new BusinessException(resource + "已存在!");
            }

            if (platUser.getRole() == ROLE_STUDENT && platUserPO.getClassId() != platUser.getClassId()) {
                //先查询他原有的排课信息
                Set<Long> lessonIdOldset = new HashSet<>();//123
                Set<Long> lessonIdNewset = new HashSet<>();//234
                if (true) {
                    PlatLessonStudentExample example = new PlatLessonStudentExample();
                    PlatLessonStudentExample.Criteria exampleCriteria = example.createCriteria();
                    exampleCriteria.andUserIdEqualTo(platUser.getId());
                    List<PlatLessonStudent> list = platLessonStudentMapper.selectByExample(example);

                    for (PlatLessonStudent lessonStudent : list) {
                        lessonIdOldset.add(lessonStudent.getLessonId());
                    }
                }
                if (true) {
                    PlatLessonStudentExample example = new PlatLessonStudentExample();
                    PlatLessonStudentExample.Criteria exampleCriteria = example.createCriteria();
                    exampleCriteria.andClassIdEqualTo(platUser.getClassId());
                    List<PlatLessonStudent> list = platLessonStudentMapper.selectByExample(example);

                    for (PlatLessonStudent lessonStudent : list) {
                        lessonIdNewset.add(lessonStudent.getLessonId());
                    }
                }

                //不能看的
                for (Long lessonId : lessonIdOldset) {
                    if (!lessonIdNewset.contains(lessonId)) {
                        PlatLessonStudentExample example = new PlatLessonStudentExample();
                        PlatLessonStudentExample.Criteria exampleCriteria = example.createCriteria();
                        exampleCriteria.andUserIdEqualTo(platUser.getId());
                        exampleCriteria.andLessonIdEqualTo(lessonId);
                        List<PlatLessonStudent> list = platLessonStudentMapper.selectByExample(example);

                        for (PlatLessonStudent lessonStudent : list) {
                            lessonStudent.setState(STATE_DELETE);
                            platLessonStudentMapper.updateByPrimaryKey(lessonStudent);
                        }
                    }
                }

                //能看的
                for (Long lessonId : lessonIdNewset) {
                    if (!lessonIdOldset.contains(lessonId)) {
                        //添加
                        PlatLessonStudentExample example = new PlatLessonStudentExample();
                        PlatLessonStudentExample.Criteria exampleCriteria = example.createCriteria();
                        exampleCriteria.andLessonIdEqualTo(lessonId);
                        List<PlatLessonStudent> list = platLessonStudentMapper.selectByExample(example);

                        Set<Long> scheduleSet = new HashSet<>();
                        for (PlatLessonStudent lessonStudent : list) {
                            if (scheduleSet.contains(lessonStudent.getScheduleId())) {
                                continue;
                            }
                            PlatLessonStudent platLessonStudent = new PlatLessonStudent();
                            platLessonStudent.setLessonId(lessonStudent.getLessonId());
                            platLessonStudent.setUserId(platUser.getId());
                            platLessonStudent.setState(0);
                            platLessonStudent.setCreateTime(new Date());
                            platLessonStudent.setScheduleId(lessonStudent.getScheduleId());
                            platLessonStudent.setClassId(platUser.getClassId());
                            platLessonStudent.setScore("");
                            platLessonStudent.setCompleteTime("");
                            platLessonStudentMapper.insert(platLessonStudent);

                            scheduleSet.add(lessonStudent.getScheduleId());
                        }
                    } else {
                        //改状态
                        PlatLessonStudentExample example = new PlatLessonStudentExample();
                        PlatLessonStudentExample.Criteria exampleCriteria = example.createCriteria();
                        exampleCriteria.andLessonIdEqualTo(lessonId);
                        List<PlatLessonStudent> list = platLessonStudentMapper.selectByExample(example);

                        Set<Long> scheduleSet = new HashSet<>();
                        for (PlatLessonStudent lessonStudent : list) {
                            if (scheduleSet.contains(lessonStudent.getScheduleId())) {
                                continue;
                            }
                            if (lessonStudent.getState() == STATE_DELETE) {
                                lessonStudent.setState(STATE_END);
                                platLessonStudentMapper.updateByPrimaryKey(lessonStudent);
                            }
                        }
                    }
                }
            }

            platUser.setUpdateTime(new Date());
            platUser.setUpdateBy(loginUser.getNickName());
            platUserMapper.updateByPrimaryKeySelective(platUser);
            return;
        }

        PlatUser platUserPO = platUserMapper.selectByNumber(platUser.getUserName());
        if (platUserPO != null) {
            throw new BusinessException(resource + "已存在!");
        }

        platUser.setCreateTime(new Date());
        platUser.setCreateBy(loginUser.getNickName());
        platUserMapper.insert(platUser);
    }

    private List<PlatUser> getMyTeacherList(PlatUser platUser, Integer[] roles) {
        PlatUserExample platUserExample = new PlatUserExample();
        platUserExample.setOrderByClause("role," + orderByClause);
        PlatUserExample.Criteria criteria = platUserExample.createCriteria();
        if (platUser != null) {
            if (platUser.getRole() != null) {
                criteria.andRoleEqualTo(platUser.getRole());
            }
            if (platUser.getCollegeId() != null) {
                criteria.andCollegeIdEqualTo(platUser.getCollegeId());
            }
            if (platUser.getMajorId() != null) {
                criteria.andMajorIdEqualTo(platUser.getMajorId());
            }
            if (platUser.getClassId() != null) {
                criteria.andClassIdEqualTo(platUser.getClassId());
            }
            if (!StringUtils.isEmpty(platUser.getNickName())) {
                criteria.andNickNameLike(LIKE + platUser.getNickName() + LIKE);
            }
            if (!StringUtils.isEmpty(platUser.getUserName())) {
                criteria.andUserNameLike(LIKE + platUser.getUserName() + LIKE);
            }
        }

        List<Integer> roleList = new ArrayList<>();
        for (Integer role : roles) {
            roleList.add(role);
        }

        criteria.andRoleIn(roleList);
        return platUserMapper.selectByExample(platUserExample);
    }
}
